//
//	ExtendedApp.m -- a class to make extra information available via the
//		application object.  If you use this object, you must link
//		against ni_s or you'll get errors!
//		Written by Don Yacktman (c) 1993 by Don Yacktman.
//				Version 1.0.  All rights reserved.
//
//		This is a free object!  Contact the author for the latest version.
//		Don Yacktman, 4279 N. Ivy Lane, Provo, UT, 84604
//		e-mail:  Don_Yacktman@byu.edu
//
//		You may use and copy this class freely as long as you
//		comply with the following terms:
//			(1) Do not remove the author's name or any of the
//				copyright notices from this file.
//			(2) If you redistribute an application which uses this
//				object, you must either include the source code for
//				this object with the application or state in your
//				application's documentation that you (a) use this
//				object and (b) where to obtain the source code for
//				the object.
//			(3) In no way shall the author or his employer(s) be held
//				responsible for any damages caused by what this object
//				does or does not do.
//			(4) You have no warranty whatsoever that this object is
//				good for any purpose at all.  If you find it useful
//				for something, consider yourself lucky and leave it at that.
//

#import <daymisckit/daymisckit.h>
#import <strings.h>
#import <libc.h>		// for chdir, getwd
#import <nikit/NIDomain.h>
#import <netinfo/ni.h>

@implementation ExtendedApp

+ new;	// application uses new, not init.  Want to save path to app
{		// and obtain other misc. info after Application does it's init.
    self = [super new];
	gethostname(realHostName, MAXHOSTNAMELEN);
	userRealName = [self realNameFor:NXUserName()];
	return self;
}


- (const char *)appDirectory; { return [[NXBundle mainBundle] directory]; }
- (int)userIDNum { return getuid(); }
- (int)groupIDNum { return getgid(); }
- (int)effectiveUserIDNum { return geteuid(); }
- (int)effectiveGroupIDNum { return getegid(); }
- (unsigned long int)hostID { return gethostid(); }
- (NXAtom)userHomeDirectory { return NXHomeDirectory(); }
- (NXAtom)userLoginName { return NXUniqueString(NXUserName()); }
- (NXAtom)userRealName { return userRealName; }
- (NXAtom)realHostName { return NXUniqueString(realHostName); }

// Attempt to get the real name corresponding to user id.
// This will work for local users or network users who are in the
// root domain.  Any other domain will most likely fail, and we
// then fall back to the login name.  If you know of a more general
// way to do this search that will _always_ be successful, or a
// better way to get this information, please let me know!
- (NXAtom)realNameFor:(NXAtom)userId
{
	id	niDomain; ni_status connectStatus;
	char path[MAXPATHLEN]; void *domainHandle;
	ni_id rootID; ni_namelist realNameList;
	char *name;

	niDomain = [[NIDomain allocFromZone:[self zone]] init];
	strcpy(path, "/users/"); strcat(path, userId);
	// try local domain first
	if (connectStatus = [niDomain setConnection:"."]) {
		NXLogError("%s:  NIDomain -setConnection:\".\" returned %s.\n",
					[NXApp appName], ni_error(connectStatus));
		return NXUniqueString(userId);
	}
	domainHandle = [niDomain getDomainHandle];
	if (connectStatus = ni_root(domainHandle, &rootID)) {
		NXLogError("%s:  ni_root returned %s.\n",
				[NXApp appName], ni_error(connectStatus));
		return NXUniqueString(userId);
	}
	if (connectStatus = ni_pathsearch(domainHandle, &rootID, path)) {
		// try in root domain, then, since not in local.
		niDomain = [[NIDomain allocFromZone:[self zone]] init];
		if (connectStatus = [niDomain setConnection:"/"]) {
			NXLogError("%s:  NIDomain -setConnection:\"/\" returned %s.\n",
					[NXApp appName], ni_error(connectStatus));
			return NXUniqueString(userId);
		}
		domainHandle = [niDomain getDomainHandle];
		if (connectStatus = ni_root(domainHandle, &rootID)) {
			NXLogError("%s:  ni_root returned %s.\n",
					[NXApp appName], ni_error(connectStatus));
			return NXUniqueString(userId);
		}
		if (connectStatus = ni_pathsearch(domainHandle, &rootID, path)) {
			NXLogError("%s:  ni_pathsearch (%s) returned %s.\n",
					[NXApp appName], path, ni_error(connectStatus));
			return NXUniqueString(userId);
		}
	}
	if (connectStatus = ni_lookupprop(domainHandle, &rootID,
			"realname", &realNameList)) {
		NXLogError("%s:  ni_lookupprop returned %s.\n",
				[NXApp appName], ni_error(connectStatus));
		return NXUniqueString(userId);
	}
	name = *(realNameList.ni_namelist_val);
	return NXUniqueString(name);
}

@end
